﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Caliburn.Core;
using Caliburn.PresentationFramework;
using Caliburn.PresentationFramework.ApplicationModel;
using Microsoft.Practices.Composite.Modularity;
using XWord.WPF.ApplicationFramework.Controls;

namespace XWord.WPF.ApplicationFramework
{
    public class BootstrapperApplication : CaliburnApplication
    {
        /// <summary>
        /// Initializes the modules. May be overwritten in a derived class to use a custom Modules Catalog
        /// </summary>
        protected virtual void InitializeModules()
        {
            var manager = Container.GetInstance<IModuleManager>();
            manager.Run();
        }

        protected IEnumerable<Assembly> GetAllModuleAssemblies()
        {
            return Container.GetInstance<IModuleCatalog>().Modules
                .Select(o => Assembly.Load(new AssemblyName(o.ModuleName)));
            //var allAssemblies = base.SelectAssemblies().Union(assemblies).ToArray();
        }

        protected override void ShowMainWindow(object rootModel)
        {
            base.ShowMainWindow(rootModel);
            this.Dispatcher.BeginInvoke(InitializeModules, DispatcherPriority.Render);
        }

        public virtual void LoadModuleAssemblies()
        {
            var assemblySource = Container.GetInstance<IAssemblySource>();
            GetAllModuleAssemblies().Apply(assemblySource.Add);
        }

        #region ResourceDictionary

        public void AddResourceDictionary(ResourceDictionary dictionary)
        {
            EnsureMergedDictionaries();
            Resources.MergedDictionaries.Add(dictionary);
        }

        public void RemoveResourceDictionary(ResourceDictionary dictionary)
        {
            EnsureMergedDictionaries();

            int index = Resources.MergedDictionaries.IndexOf(dictionary);
            if (index >= 0)
                Resources.MergedDictionaries[index] = new ResourceDictionary();
        }

        public void EnsureMergedDictionaries()
        {
            if (Resources == null)
            {
                Resources = new ResourceDictionary();
            }

            if (Resources.MergedDictionaries.Count == 0)
            {
                Resources.MergedDictionaries.Add(new ResourceDictionary());
            }
        }

        #endregion

        /// <summary>
        /// Current Application
        /// </summary>
        public new static BootstrapperApplication Current
        {
            get { return Application.Current as BootstrapperApplication; }
        }

        private static object DoEventsCore(object arg)
        {
            var frame = arg as DispatcherFrame;
            if (frame != null)
                frame.Continue = false;

            return null;
        }


        private ITrayIcon _trayIcon;
        public ITrayIcon TrayIcon
        {
            get
            {
                if (_trayIcon == null) _trayIcon = Controls.TrayIcon.CreateTrayIcon();
                return _trayIcon;
            }
            set
            {
                _trayIcon = value;
            }
        }
    }
}